#include "plat_types.h"

#if USE_LV_DM != 0

#include "stdlib.h"

//#include "plat_config_defs.h"
//#include "ui_os_api.h"
//#include "ui_log_api.h"
//#include "nvram.h"
//#include "nw_api.h"

#include "cus_dm_register_def.h"
#include "dm_register.h"
#include "dm_cmid.h"


static struct dm_register_config *cur_dm_config = NULL;

u16 get_dm_nv_id(void)
{
	ASSERT(cur_dm_config != NULL);
	return (u16)cur_dm_config->dm_nv_id;
}

u8 get_telecom_dm_mode(void)
{
	ASSERT(cur_dm_config != NULL);
	return cur_dm_config->telecom_dm_mode;
}

u8 get_cmcc_dm_mode(void)
{
	ASSERT(cur_dm_config != NULL);
	return cur_dm_config->cmcc_dm_mode;
}

u8 get_unicom_dm_mode(void)
{
	ASSERT(cur_dm_config != NULL);
	return cur_dm_config->unicom_dm_mode;
}

u8 get_dm_demo_mode(void)
{
	ASSERT(cur_dm_config != NULL);
	return cur_dm_config->demo_mode;
}

static int __get_sim_type(char *plmn)
{
	if (strcmp(plmn, "46000") == 0 || strcmp(plmn, "46002") == 0
	    || strcmp(plmn, "46004") == 0 || strcmp(plmn, "46007") == 0)
		return CHINA_MOBILE;
	else if (strcmp(plmn, "46001") == 0 || strcmp(plmn, "46006") == 0
		 || strcmp(plmn, "46009") == 0)
		return CHINA_UNICOM;
	else if (strcmp(plmn, "46003") == 0 || strcmp(plmn, "46005") == 0)
		return CHINA_TELECOM_CDMA;
	else if (strcmp(plmn, "46011") == 0)
		return CHINA_TELECOM_LTE;
	else
		return UNKNOW_SIM;
}

struct sim_info *get_current_sim_info(void)
{
	char plmn1[5] = { 0 };
	char plmn2[5] = { 0 };
	static int flag = 0;
	static struct sim_info cur_sim_info = {
		0, 0,
		UNKNOW_SIM, UNKNOW_SIM,
		ICCID_WITH_NO_SIM_INSTRTED, ICCID_WITH_NO_SIM_INSTRTED,
		IMSI_WITH_NO_SIM_INSTRTED, IMSI_WITH_NO_SIM_INSTRTED};

	if (0 == flag) {
		cur_sim_info.sim1_flag = DM_IsSimExist(0);
		cur_sim_info.sim2_flag = DM_IsSimExist(1);

		if (cur_sim_info.sim1_flag) {
			strncpy(plmn1, (const char *)DM_NwGetImsi(CMID_SIM_0), 5);
			cur_sim_info.sim1_type = __get_sim_type(plmn1);
			cur_sim_info.iccid1 = (const char *)DM_NwGetIccid(CMID_SIM_0);
			cur_sim_info.imsi1 = (const char *)DM_NwGetImsi(CMID_SIM_0);
		}

		if (cur_sim_info.sim2_flag) {
			strncpy(plmn2, (const char *)DM_NwGetImsi(CMID_SIM_1), 5);
			cur_sim_info.sim2_type = __get_sim_type(plmn2);
			cur_sim_info.iccid2 = (const char *)DM_NwGetIccid(CMID_SIM_1);
			cur_sim_info.imsi2 = (const char *)DM_NwGetImsi(CMID_SIM_1);
		}

		CTDM_LOG("[DM] current sim info:\n");
		CTDM_LOG("[DM] sim1_flag:%d, sim1_type:%d\n", cur_sim_info.sim1_flag, cur_sim_info.sim1_type);
		CTDM_LOG("[DM] sim2_flag:%d, sim2_type:%d\n", cur_sim_info.sim2_flag, cur_sim_info.sim2_type);
		CTDM_LOG("[DM] imsi1:%s\n", cur_sim_info.imsi1);
		CTDM_LOG("[DM] imsi2:%s\n", cur_sim_info.imsi2);
		CTDM_LOG("[DM] iccid1:%s\n", cur_sim_info.iccid1);
		CTDM_LOG("[DM] iccid2:%s\n", cur_sim_info.iccid2);

		flag = 1;
	}

	return &cur_sim_info;
}

struct dm_register_record *get_current_dm_record(void)
{
	static struct dm_register_record dm_nv_record;
	static int flag;
	uint32_t nv_len = 0;

	if (0 == flag) {
		nv_len = sizeof(nv_watch_dm_t);
		if(nv_len != UI_NV_Read_Req(NV_SECTION_UI_DM, 0, nv_len, (uint8_t *)&dm_nv_record)) {
				CTDM_LOG("[DM] read DM NV failed!\n");
				return NULL;
		}

		CTDM_LOG("[DM] current dm nv record:\n");
		CTDM_LOG("[DM] nv imsi1:%s\n", dm_nv_record.IMSI1);
		CTDM_LOG("[DM] nv imsi2:%s\n", dm_nv_record.IMSI2);
		CTDM_LOG("[DM] nv iccid1:%s\n", dm_nv_record.UEICCID1);
		CTDM_LOG("[DM] nv iccid2:%s\n", dm_nv_record.UEICCID2);

		flag = 1;
	}

	return &dm_nv_record;
}

static void* dm_task_handle = NULL;

void send_dm_event(uint32_t evt, uint32_t register_type)
{
	UI_EVENT dm_evt = {0, 0, 0, 0};
	ASSERT(dm_task_handle != NULL);

	dm_evt.nEventId = evt;
	dm_evt.nParam1 = register_type;
	uos_send_event(dm_task_handle, &dm_evt, UOS_WAIT_FOREVER, UOS_EVENT_PRI_NORMAL);
}

static void dm_task_entry(void *dm_handle)
{
	int ret;
	struct sim_info *cur_sim_info;
	UI_EVENT dm_evt;
	int flag = 0;

	// wait for system enter idle state
	uos_sleep(6000);  /* 30s (1 os tick == 5 ms) */

	cur_sim_info = get_current_sim_info();
	cur_dm_config = get_dm_configuration();

	if ((0 == cur_sim_info->sim1_flag) && (0 == cur_sim_info->sim2_flag)) {
		CTDM_LOG("[DM] no sim insert, exit DM module\n");
		goto exit;
	}

	if (!get_current_dm_record()) {
			CTDM_LOG("[DM] read DM NV failed, exit DM module\n");
			goto exit;
	}

#ifdef DM_VERSION_1
	CTDM_LOG("[DM] DM VERSION 1\n");
#else
#ifdef DM_VERSION_2
	CTDM_LOG("[DM] DM VERSION 2\n");
#endif
#endif

	CTDM_LOG("[DM] build time %s %s\n", __DATE__, __TIME__);

	ASSERT(cur_dm_config != NULL);

	CTDM_LOG("[DM] dm configuration: telecom:%d cmcc:%d unicom:%d nv_id:%d\n",
		cur_dm_config->telecom_dm_mode,
		cur_dm_config->cmcc_dm_mode,
		cur_dm_config->unicom_dm_mode,
		cur_dm_config->dm_nv_id);

	switch (get_telecom_dm_mode()) {
		case DM_DATA_MODE:
			flag++;
			send_dm_event(TELECOM_DM_REQUEST, DM_REGISTER_TYPE_DATA);
			break;

		case DM_SMS_MODE:
			flag++;
			send_dm_event(TELECOM_DM_REQUEST, DM_REGISTER_TYPE_SMS);
			break;

		case DM_SMS_DATA_MODE:
			flag++;
			send_dm_event(TELECOM_DM_REQUEST, DM_REGISTER_TYPE_SMS);
			flag++;
			send_dm_event(TELECOM_DM_REQUEST, DM_REGISTER_TYPE_DATA);
			break;

		default:
			break;
	}

#if 0
	if (get_cmcc_dm_mode()) {
		flag++;
		send_dm_event(CMCC_DM_REQUEST);
	}

	if (get_unicom_dm_mode()) {
		flag++;
		send_dm_event(UNICOM_DM_REQUEST);
	}
#endif

	if (0 == flag) {
		CTDM_LOG("[DM] (config empty)exit DM module!\n");
		goto exit;
	}

	while (1) {
		uos_wait_event(dm_task_handle, &dm_evt, UOS_WAIT_FOREVER);

		ret = NO_REGISTER_REQUIRED;

		switch (dm_evt.nEventId) {
		case TELECOM_DM_REQUEST:
			if (cur_sim_info->sim1_type == CHINA_TELECOM_LTE || cur_sim_info->sim2_type == CHINA_TELECOM_LTE) {
				ret = do_telecom_dm(dm_evt.nParam1);
			} else {
				CTDM_LOG("[DM] no TELECOM sim card insert!\n");
			}
			break;

#if 0
		case CMCC_DM_REQUEST:
			if (cur_sim_info->sim1_type == CHINA_MOBILE || cur_sim_info->sim2_type == CHINA_MOBILE) {
				ret = do_cmcc_dm();
			} else {
				CTDM_LOG("[DM] no CMCC sim card insert!\n");
			}
			break;

		case UNICOM_DM_REQUEST:
			if (cur_sim_info->sim1_type == CHINA_UNICOM || cur_sim_info->sim2_type == CHINA_UNICOM) {
				ret = do_unicom_dm();
			} else {
				CTDM_LOG("[DM] no UNICOM sim card insert!\n");
			}
			break;
#endif

		default:
			break;
		}

		if (ret != REGISTER_FAILED)
			flag--;

		if (0 == flag)
			break;
	}

exit:

	CTDM_LOG("[DM] exit DM module! ret=%d\n", ret);

	uos_delete_task((TASK_HANDLE *)dm_task_handle);
}

void dm_start(void)
{
	static int flag = 0;

	if (1 == flag) {
		return;
	}
	flag = 1;

	CTDM_LOG("[DM] create dm task!\n");

#if UI_IN_XIP
    static lv_xip_thread param;
    param.func = dm_task_entry;
    param.params = NULL;
    dm_task_handle = uos_create_task(
         lv_xip_thread_entry,
         &param,
         TASK_MSGQ_SIZE_16,
         10240,
         210,
         "DMTask");
#else
	dm_task_handle = uos_create_task(
		dm_task_entry,
		NULL,
		TASK_MSGQ_SIZE_16,
		10240,
		210,
		"DMTask");
#endif
	ASSERT(dm_task_handle != NULL);
}

#endif
